package com.sdy.kzyy.biz.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdy.common.model.BizException;
import com.sdy.common.utils.Assert;
import com.sdy.kzyy.biz.dto.StoreManageDTO;
import com.sdy.kzyy.biz.model.Area;
import com.sdy.kzyy.biz.model.Store;
import com.sdy.kzyy.biz.mapper.StoreMapper;
import com.sdy.kzyy.biz.model.StoreInventory;
import com.sdy.kzyy.biz.model.User;
import com.sdy.kzyy.biz.service.*;
import com.sdy.kzyy.biz.dto.StoreDTO;
import com.sdy.mvc.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zzq
 * @since 2020-03-04
 */
@Slf4j
@Service
public class StoreServiceImpl extends BaseServiceImpl<Store> implements StoreService {
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private KeyValueConfigurationsService keyValueConfigurationsService;
    @Autowired
    private UserService userService;
    @Autowired
    private StoreInventoryService storeInventoryService;
    @Autowired
    private AreaService areaService;

    public static String randomNum() {
        long dateEx = System.currentTimeMillis();
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String timeEx = dateFormat.format(dateEx);
        int aEx = (int) (Math.random() * 900 + 100);
        String randomThree = Integer.toString(aEx);
        String randomNum = timeEx + randomThree;
        return randomNum;
    }

    @Override
    public List<StoreDTO> getAreaPage(String areaCode, Page<StoreDTO> page) {
        return storeMapper.getAreaPage(areaCode, page);
    }

    @Override
    public Integer getAreaPageSize(String areaCode) {
        return storeMapper.getAreaPageSize(areaCode);
    }

    @Override
    public List<StoreDTO> getNamePage(String name, Page<StoreDTO> page) {
        return storeMapper.getNamePage(name, page);
    }

    @Override
    public Integer getNamePageSize(String name) {
        return storeMapper.getNamePageSize(name);
    }

/*    @Override
    public boolean updateExtractTime() {
        String time = keyValueConfigurationsService.getExtractTime();
        Store store = new Store();
        store.setAppointTime(time);
        return update(store, new UpdateWrapper<Store>());
    }*/

    @Override
    public List<StoreManageDTO> getStoreManagePage(Page page, String name, String storeCode) {
        return storeMapper.getStoreManagePage(page, name, storeCode);
    }

    @Override
    public Boolean saveStorManage(StoreManageDTO storeManageDTO) throws BizException {
        // 校验传入数据
        checkDate(storeManageDTO);
        String num = randomNum();
        Date date = new Date();
        // 新增药店数据
        boolean saveStore = save(new Store()
                .setName(storeManageDTO.getName())
                .setStoreCode(num)
                .setAreaCode(storeManageDTO.getAreaCode())
                .setAddress(storeManageDTO.getAddress())
                .setContacts(storeManageDTO.getContacts())
                .setContactsPhone(storeManageDTO.getContactsPhone())
                .setWeek(storeManageDTO.getWeek())
                .setAppointTime(storeManageDTO.getAppointTime())
                .setCreateTime(date)
                .setWeekTime(storeManageDTO.getWeekTime())
        );
        Assert.notTrue(saveStore, "新增药店数据出错!");

        //新增存货信息
        boolean saveSi = storeInventoryService.save(new StoreInventory()
                .setStoreCode(num)
                .setCreateTime(date)
                .setKzCount(storeManageDTO.getReplenishNextday())
                .setAllCount(storeManageDTO.getReplenishNextday())
                .setOnceCount(Integer.valueOf(keyValueConfigurationsService.getLimitationCount()))
        );
        Assert.notTrue(saveSi, "新增存货数据出错!");

        return true;
    }

    @Override
    public StoreManageDTO getStoreManageOne(Integer id) throws BizException {
        // 查询药店数据
        Store byId = getById(id);
        Assert.isTrue(byId == null, "药店基础信息有问题,请反馈!");
        String storeCode = byId.getStoreCode();
        Assert.isTrue(StringUtils.isBlank(storeCode), "药店基础信息有问题,请反馈!");
        Area area = areaService.getOne(Wrappers.<Area>lambdaQuery().eq(Area::getCode, byId.getAreaCode()));
        StoreInventory one = storeInventoryService.getOne(Wrappers.<StoreInventory>lambdaQuery()
                .eq(StoreInventory::getStoreCode, storeCode));
        StoreManageDTO storeManageDTO = new StoreManageDTO()
                .setId(id)
                .setName(byId.getName())
                .setAreaName(area.getName())
                .setAreaCode(byId.getAreaCode())
                .setAddress(byId.getAddress())
                .setAllCount(one.getAllCount())
                .setKzCount(one.getKzCount())
                .setContacts(byId.getContacts())
                .setContactsPhone(byId.getContactsPhone())
                .setWeek(byId.getWeek())
                .setAppointTime(byId.getAppointTime())
                .setReplenishNextday(one.getReplenishNextDay());
        return storeManageDTO;
    }

    @Override
    public Boolean updateStorManage(StoreManageDTO storeManageDTO) throws BizException {
        // 校验传入数据
        checkDate(storeManageDTO);
        Date date = new Date();
        Store byId = getById(new Store().setId(storeManageDTO.getId()));
        // 修改药店数据
        boolean updateStore = updateById(new Store()
                .setName(storeManageDTO.getName())
                .setId(storeManageDTO.getId())
                .setAreaCode(storeManageDTO.getAreaCode())
                .setAddress(storeManageDTO.getAddress())
                .setContacts(storeManageDTO.getContacts())
                .setContactsPhone(storeManageDTO.getContactsPhone())
                .setWeek(storeManageDTO.getWeek())
                .setAppointTime(storeManageDTO.getAppointTime())
                .setWeekTime(storeManageDTO.getWeekTime())
                .setUpdateTime(date)
        );
        Assert.notTrue(updateStore, "修改药店数据出错!");
        StoreInventory one = storeInventoryService.getOne(Wrappers.<StoreInventory>lambdaQuery()
                .eq(StoreInventory::getStoreCode, byId.getStoreCode()));
        int replenishNextDay = one.getReplenishNextDay();
        int replenishNextday = storeManageDTO.getReplenishNextday();
        int overReplenish = replenishNextDay + replenishNextday;
        // 判断增减是否小于剩余量和已经填了的补货量的和
        int kzCount = one.getKzCount();
        int endNum = kzCount + overReplenish;
        Assert.isTrue(endNum < 0, "次日提供量不可为负数!");
        // 更新存货信息
        boolean updateSi = storeInventoryService.update(Wrappers.<StoreInventory>lambdaUpdate()
                .eq(StoreInventory::getStoreCode, byId.getStoreCode())
                .set(StoreInventory::getReplenishNextDay, overReplenish)
                .set(StoreInventory::getUpdateTime, date)
        );
        Assert.notTrue(updateSi, "修改存货数据出错!");
        return true;
    }

    @Override
    public Boolean delStorManage(Integer id, Integer state) throws BizException {
        Date date = new Date();
        int cancel = 0;
        int cancelRecovery = 0;
        if (state == 1) {
            state = 2;
            cancelRecovery = 2;
            // 隐藏店铺数据
            Store byId = getById(id);
            boolean update = updateById(new Store().setId(id).setStoreStatus(state).setUpdateTime(date));
            Assert.notTrue(update, "删除店铺数据出错!");
            // 取消用户权限
            String storeCode = byId.getStoreCode();
            Assert.isTrue(StringUtils.isBlank(storeCode), "请检查店铺信息的完整性!");
            List<User> list = userService.list(Wrappers.<User>lambdaQuery().eq(User::getStoreCode, storeCode).eq(User::getQrCheck, 1));
            List<Integer> collect = list.stream().map(User::getId).collect(Collectors.toList());
            if (collect.size() > 0) {
                boolean b = userService.update(Wrappers.<User>lambdaUpdate()
                        .eq(User::getCancelReason, cancel)
                        .inOrThrow(User::getId, collect)
                        .set(User::getQrCheck, state)
                        .set(User::getUpdateTime, date)
                        .set(User::getCancelReason, cancelRecovery));
                Assert.notTrue(b, "删除店铺负责人扫码权限出错!");
            }
        } else if (state == 2) {
            state = 1;
            cancel = 2;
            // 恢复店铺数据
            Store byId = getById(id);
            boolean update = updateById(new Store().setId(id).setStoreStatus(state).setUpdateTime(date));
            Assert.notTrue(update, "恢复店铺数据出错!");
            // 取消用户权限
            String storeCode = byId.getStoreCode();
            Assert.isTrue(StringUtils.isBlank(storeCode), "请检查店铺信息的完整性!");
            List<User> list = userService.list(Wrappers.<User>lambdaQuery().eq(User::getStoreCode, storeCode).eq(User::getCancelReason, 2));
            List<Integer> collect = list.stream().map(User::getId).collect(Collectors.toList());
            if (collect.size() > 0) {
                boolean b = userService.update(Wrappers.<User>lambdaUpdate()
                        .eq(User::getCancelReason, cancel)
                        .inOrThrow(User::getId, collect)
                        .set(User::getQrCheck, state)
                        .set(User::getUpdateTime, date)
                        .set(User::getCancelReason, cancelRecovery));
                Assert.notTrue(b, "恢复店铺负责人扫码权限出错!");
            }
        }
        return true;
    }

    public void checkDate(StoreManageDTO storeManageDTO) throws BizException {
        Assert.isTrue(StringUtils.isBlank(storeManageDTO.getName()), "请规范填写药店名称!");
        Assert.isTrue(storeManageDTO.getAreaCode() == null || storeManageDTO.getAreaCode().equals(""), "请选择药店地址!");
        Assert.isTrue(StringUtils.isBlank(storeManageDTO.getAddress()), "请规范填写详细地址数据!");
        Assert.isTrue(storeManageDTO.getReplenishNextday() == null || storeManageDTO.getReplenishNextday().equals(""), "请规范填写补货信息!");
        String regex = "^-?[0-9]\\d*$";
        String replenishNextday = String.valueOf(storeManageDTO.getReplenishNextday());
        boolean matches = Pattern.matches(regex, replenishNextday);
        Assert.notTrue(matches, "请填写整数!");
        Assert.isTrue(StringUtils.isBlank(storeManageDTO.getContacts()), "请规范填写联系人名称!");
        Assert.isTrue(!storeManageDTO.getContactsPhone().matches(com.sdy.common.constant.Constants.REGEX_PHONE), "手机号格式错误!");
        Assert.isTrue(storeManageDTO.getAppointTime() == null || storeManageDTO.getAppointTime().equals(""), "请规范填写可取货时间信息!");
    }

}
